import { ref } from 'vue'

import { base64ToFilePath } from '@/libs/file-utils'

const canvasId = 'cooolar-canvas'
const canvasWidth = ref(2)
const canvasHeight = ref(2)
const canvasList: {
  id: number
  canvas: any
}[] = []

export { canvasId, canvasWidth, canvasHeight, canvasList }

let canvas: any = null
let ctx: any = null

// #ifdef WEB
canvas = document.createElement('canvas')
ctx = canvas.getContext('2d')
// #endif

// #ifdef MP-WEIXIN
canvas = uni.createOffscreenCanvas({ type: '2d' })
ctx = canvas.getContext('2d')
// #endif

/**
 * 获取Canvas实例
 * @param w 宽
 * @param h 高
 */
const getCanvas = async (w?: number, h?: number) => {
  // #ifdef MP-TOUTIAO
  if (canvasList.length) {
    canvas = canvasList[canvasList.length - 1].canvas
    ctx = canvas.getContext('2d')
  }
  // #endif

  if (w && h) {
    canvasWidth.value = w
    canvasHeight.value = h

    // #ifdef WEB || MP
    canvas.width = w
    canvas.height = h
    // #endif

    // #ifdef APP || MP-TOUTIAO
    await new Promise(resolve => setTimeout(resolve, 200))
    // #endif
  }

  // #ifdef APP
  ctx = uni.createCanvasContext(canvasId) as any
  // #endif

  if (!ctx) throw '不支持Canvas处理'

  return { canvas, ctx }
}

/**
 * 获取图片实例
 * @param srcPath 图片链接
 */
const getImageInstance = async (srcPath: string) => {
  // #ifdef MP-TOUTIAO
  await getCanvas()
  // #endif

  return await new Promise<HTMLImageElement>((resolve, reject) => {
    // #ifdef MP
    {
      const image = canvas.createImage() as HTMLImageElement

      image.onload = () => resolve(image)
      image.onerror = reject
      image.src = srcPath

      // 微信端bug： https://developers.weixin.qq.com/community/develop/doc/00020a1de78788cfa4437459165c00?highLine=Image%25E7%25BB%2584%25E4%25BB%25B6%25E6%258A%25A5%25E9%2594%2599
    }
    // #endif

    // #ifdef WEB
    {
      const image = new Image()

      image.crossOrigin = 'anonymous'
      image.onload = () => resolve(image)
      image.onerror = reject
      image.src = srcPath
    }
    // #endif
  })
}

/**
 * 保存当前Canvas图像到临时文件
 * @param fileType 导出格式
 * @param quality 导出质量
 */
const getCanvasImage = async (
  fileType: 'jpeg' | 'png' = 'jpeg',
  quality = 0.95,
): Promise<string> => {
  return new Promise((resolve, reject) => {
    // #ifdef WEB || MP
    {
      const base64 = canvas.toDataURL('image/' + fileType, quality)

      if (!base64) throw '图片转换失败'

      base64ToFilePath(base64).then(resolve)
    }
    // #endif

    // #ifdef APP
    {
      uni.canvasToTempFilePath({
        canvasId,
        fileType,
        quality,
        success(res) {
          res.tempFilePath ? resolve(res.tempFilePath) : reject()
        },
        fail: reject,
      })
    }
    // #endif
  })
}

/**
 * 重置画布实例
 */
const resetCanvas = () => (ctx = null)

export { getCanvas, getImageInstance, getCanvasImage, resetCanvas }
